import React, { Component } from "react";
import { Card, Grid, Icon, Tree, Loader, Button } from "@scuf/common";
import { Alert, Modal, Form, InputNumber, SelectPicker } from "rsuite";
import { Menu, Item, contextMenu } from "react-contexify";

import SockJS from "sockjs-client";
import Stomp from "stompjs";

import http from "../../../components/http/http";
import Graphic from "../../../components/graphic/component-list";
import rest from "../../../assets/rest";
import CustomField from "../../../components/common/customField";

import GraphicCss from "./graphic.module.css";

class GraphicList extends Component {
  constructor(props) {
    super(props);
    let id = this.props.match.params.locationId;
    let locationArr = id.split("_");
    this.state = {
      id: id,
      locationId: locationArr[locationArr.length - 1],
      components: [],
      //view
      views: [],
      viewTitle: "Please choose a view",
      activeViewId: 0,
      width: "100%",
      height: "100%",
      loadingView: true,
      //item
      loadingItem: false,
      currentSelectId: null,
      menuId: "pxview_list_menu",
      currentSetPoint: null,
      openControl: null,
      actionId: null,
      showBoolean: false,
      showNumeric: false,
      controlForm: {
        value: "",
      },
      stompClient: Stomp.over(
        new SockJS(`http://${window.location.host}/${rest.websocketIp}`)
      ),
      currentPerms: [],
    };
    this.loadViews = this.loadViews.bind(this);
    this.handleContextMenu = this.handleContextMenu.bind(this);
    this.handleControlMethod = this.handleControlMethod.bind(this);
    this.handleViewClick = this.handleViewClick.bind(this);
    this.handleActive = this.handleActive.bind(this);
    this.handleOnMessageReceived = this.handleOnMessageReceived.bind(this);
  }

  UNSAFE_componentWillMount() {
    let menus = window.localStorage.getItem(rest.menus);
    if (!!menus) {
      this.setState({
        currentPerms: JSON.parse(menus).filter((x) => x.name === "Workbench")[0]
          .perms,
      });
    }
    this.loadViews();
  }

  componentWillUnmount() {
    const { stompClient } = this.state;
    stompClient.disconnect();
    this.setState = (state, callback) => {
      return;
    };
  }

  componentDidMount() {
    const { stompClient } = this.state;
    stompClient.debug = null;
    stompClient.connect({});
  }

  handleOnMessageReceived(payload) {
    let result = JSON.parse(payload.body).data;
    const { components } = this.state;
    this.setState({ components: [] });
    let temp = components.map((component) => {
      let obj = {};
      let tempObj = result[component.props.id];
      if (!!tempObj) {
        let path = tempObj.imagePath;
        if (!!path) {
          obj.path = path;
        }
        obj.pointValue = tempObj.pointValue;
        obj.text = tempObj.displayText;
      }
      return Graphic.componentList(
        Object.assign(
          {
            ...component.props,
          },
          obj
        )
      );
    });
    this.setState({ components: temp });
  }

  //加载view列表
  loadViews() {
    const { locationId } = this.state;
    http
      .get(rest.pxview.pxviews, {
        params: {
          locationId: locationId,
        },
      })
      .then((response) => {
        if (response.status === 200 && response.data.code === 200) {
          this.setState({
            views: response.data.data,
            loadingView: false,
          });
        }
      });
  }

  //右键菜单
  handleContextMenu(event) {
    event = event.nativeEvent;
    event.preventDefault();
    const { menuId, components } = this.state;
    const { target: dom } = event;
    let editable = dom.getAttribute("editable");
    let currentSelectId = dom.getAttribute("id");
    let componentTypeId = components
      .filter((component) => component.key === currentSelectId)
      .map((component) => component.props.componentTypeId)[0];
    if (Number(editable) === 1) {
      componentTypeId = Number(componentTypeId);
      contextMenu.show({
        id: menuId,
        event: event,
      });
      this.setState({
        currentSelectId: currentSelectId,
        showBoolean: componentTypeId === 1,
        showNumeric: componentTypeId === 2,
      });
    }
  }

  handleControlMethod() {
    const { controlForm, currentSelectId, components, actionId } = this.state;
    let pointId = components
      .filter((component) => component.key === currentSelectId)
      .map((component) => component.props.point)[0];
    http
      .patch(rest.pxview.value, {
        actionId: actionId,
        pointId: pointId,
        val: controlForm.value,
      })
      .then((response) => {
        if (response.status !== 200 || response.data.code !== 200) {
          Alert.error("this device hasn't been tied a point");
        }
      })
      .catch((error) => {
        Alert.error("control failed");
      });
    this.setState({
      openControl: false,
    });
  }

  //点击一个view加载view item
  handleViewClick(obj) {
    const { stompClient, activeViewId } = this.state;
    const { id, name } = obj;
    stompClient.unsubscribe(`/message/realtime/${activeViewId}`);
    this.setState({
      activeViewId: id,
      viewTitle: name,
      loadingItem: true,
    });
    http
      .get(rest.pxview.detail, {
        params: {
          id: id,
        },
      })
      .then((response) => {
        if (response.status === 200 && response.data.code === 200) {
          this.setState({ components: [] });
          let width = response.data.data.width;
          let height = response.data.data.height;
          let components = response.data.data.items.map((res) => {
            return Graphic.componentList({
              id: res.uuid,
              drag: false,
              box: this.refs.box,
              width: `${(res.layoutWidth / width) * 100}%`,
              height: `${(res.layoutHeight / height) * 100}%`,
              top: `${(res.layoutTop / height) * 100}%`,
              left: `${(res.layoutLeft / width) * 100}%`,
              graphicId: res.componentId,
              editable: res.editable,
              type: res.type,
              path: res.defaultImagePath,
              point: !!res.point ? res.point.id : null,
              componentTypeId: res.componentTypeId,
            });
          });
          this.setState({
            components: components,
            loadingItem: false,
          });
          stompClient.subscribe(
            `/message/realtime/${id}`,
            this.handleOnMessageReceived
          );
          Alert.success("load success!");
        } else {
          this.setState({ loadingItem: false });
          Alert.error("load failed!");
        }
      })
      .catch((error) => {
        this.setState({ loadingItem: false });
        Alert.error("load failed!");
      });
  }

  handleActive(obj) {
    const { locationId } = this.state;
    const { id, name, width, height } = obj;
    if (!!id) {
      http
        .put(rest.pxview.pxviews, {
          id: id,
          name: name,
          width: width,
          height: height,
          locationId: locationId,
          active: true,
        })
        .then((response) => {
          if (response.status === 200 && response.data.code === 200) {
            this.loadViews();
          }
        })
        .catch((error) => {});
    }
  }

  render() {
    const {
      id,
      views,
      viewTitle,
      components,
      loadingView,
      loadingItem,
      activeViewId,
      menuId,
      openControl,
      controlForm,
      showBoolean,
      showNumeric,
      currentPerms,
    } = this.state;
    return (
      <Grid className="fixOuterHeight">
        <Grid.Row>
          <Grid.Column width={2}>
            <Card style={{ height: "100%" }}>
              <Card.Header title="Graphics"></Card.Header>
              <Card.Content>
                <Tree style={{ width: "100%" }}>
                  <Tree.Content>
                    <Loader loading={loadingView}>
                      {views.map((view) => {
                        return (
                          <Tree.Content.Item
                            key={view.id}
                            title={view.name}
                            active={activeViewId === view.id}
                            onTitleClick={() => {
                              this.handleViewClick({
                                id: view.id,
                                name: view.name,
                              });
                            }}
                            icon={
                              <Icon
                                className={GraphicCss.actionIcon}
                                name="document"
                                size="small"
                                color="blue"
                              />
                            }
                            actionRenderer={
                              currentPerms.indexOf("workbench:graphic:edit") !==
                              -1 ? (
                                <Icon
                                  className="pointer"
                                  root="common"
                                  name="brightness"
                                  size="medium"
                                  color={!!view.active ? "green" : "red"}
                                  onClick={() => {
                                    this.handleActive({
                                      id: view.id,
                                      name: view.name,
                                      width: view.width,
                                      height: view.height,
                                    });
                                  }}
                                />
                              ) : null
                            }
                          />
                        );
                      })}
                    </Loader>
                  </Tree.Content>
                </Tree>
              </Card.Content>
            </Card>
          </Grid.Column>
          <Grid.Column width={10}>
            <Card style={{ height: "100%" }}>
              <Card.Header title={viewTitle}>
                {currentPerms.indexOf("workbench:graphic:edit") !== -1 ? (
                  <Button
                    onClick={() => {
                      this.props.history.push(`/workbench/graphic-edit/${id}`);
                    }}
                    textTransform={false}
                    size="small"
                    type="secondary"
                    content="Edit"
                  />
                ) : null}
              </Card.Header>
              <Card.Content style={{ overflowX: "auto" }}>
                <div
                  ref="box"
                  style={{
                    width: this.state.width,
                    height: this.state.height,
                  }}
                  className={GraphicCss.grid}
                  onContextMenu={this.handleContextMenu}
                  onTouchEnd={this.handleContextMenu}
                >
                  <Loader loading={loadingItem}>{components}</Loader>
                </div>
                <Menu theme="dark" id={menuId}>
                  <Item
                    disabled={
                      currentPerms.indexOf("workbench:graphic:edit") === -1
                    }
                    onClick={() => {
                      this.setState({
                        show: false,
                        openControl: true,
                        actionId: 2,
                      });
                    }}
                  >
                    Emergency Override
                  </Item>
                  <Item
                    disabled={
                      currentPerms.indexOf("workbench:graphic:edit") === -1
                    }
                    onClick={() => {
                      this.setState({
                        show: false,
                        openControl: true,
                        actionId: 3,
                      });
                    }}
                  >
                    Emergency Auto
                  </Item>
                  <Item
                    disabled={
                      currentPerms.indexOf("workbench:graphic:edit") === -1
                    }
                    onClick={() => {
                      this.setState({
                        show: false,
                        openControl: true,
                        actionId: 4,
                      });
                    }}
                  >
                    Override
                  </Item>
                  <Item
                    disabled={
                      currentPerms.indexOf("workbench:graphic:edit") === -1
                    }
                    onClick={() => {
                      this.setState({
                        show: false,
                        openControl: true,
                        actionId: 5,
                      });
                    }}
                  >
                    Auto
                  </Item>
                  <Item
                    disabled={
                      currentPerms.indexOf("workbench:graphic:edit") === -1
                    }
                    onClick={() => {
                      this.setState({
                        show: false,
                        openControl: true,
                        actionId: 1,
                      });
                    }}
                  >
                    Set
                  </Item>
                </Menu>
              </Card.Content>
            </Card>
          </Grid.Column>
        </Grid.Row>
        <Modal
          size="xs"
          onHide={() => this.setState({ openControl: false })}
          show={openControl}
          backdrop="static"
        >
          <Modal.Header>
            <Modal.Title>Set Value</Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <Form
              fluid
              onChange={(formValue) => {
                this.setState({ controlForm: formValue });
              }}
              formValue={controlForm}
            >
              <CustomField
                style={{ display: showNumeric ? "block" : "none" }}
                name="value"
                label="Value:"
                accepter={InputNumber}
              />
              <CustomField
                style={{ display: showBoolean ? "block" : "none" }}
                name="value"
                label="Value:"
                block={true}
                searchable={false}
                accepter={SelectPicker}
                data={[
                  {
                    value: 1,
                    label: "True",
                  },
                  { value: 0, label: "False" },
                ]}
              />
            </Form>
          </Modal.Body>
          <Modal.Footer>
            <Button
              type="secondary"
              size="medium"
              content="Cancel"
              onClick={() =>
                this.setState({
                  openControl: false,
                })
              }
            />
            <Button
              type="primary"
              size="medium"
              content="Ok"
              onClick={this.handleControlMethod}
            />
          </Modal.Footer>
        </Modal>
      </Grid>
    );
  }
}

export default (props) => (
  <GraphicList {...props} key={props.location.pathname} />
);
